require "ParticleList.lua"

g_config={
  path='b_dd',type=0,scale=0.24,tx=0.27,ty=0.0,anchor=KuruBackgroundImageNodeAnchorType.CENTER,stretch=KuruBackgroundImageNodeStretch.FILL_HORIZONTAL,fps=10,blendmode=BlendMode.None,
}
g_hgConfig = {
  path='f_hg.png',type=1,scale=0.54,tx=0.2,ty=-0.75,anchor=KaleStickerNodeAnchorType.BOTTOM,location=KaleStickerNodeLocationType.FACE,flip=false,fps=20,blendmode=BlendMode.Normal,
}
LFET_POINT_INDEX_OF_LEFT_EYE = 45
RIGHT_POINT_INDEX_OF_RIGHT_EYE = 36
DURATION_PER_FRAME = 100.0
EMIT_COUNT_SCALE_FACTOR = 40

SnapState = {
  NORMAL = 0,
  CAPTRUEED = 1,
  VIDEOING = 2,
}

g_kuruEngineInstance = nil
--g_gyroCameraNode = nil
g_lastEmitFrameIndex = 0
g_totalElapsedTime = 4000
g_leftParticles = {}
g_rightParticles = {}
g_samplers = {}
g_frame_count = 2
isAning = true --标志小图片动画
g_bufferTime = 0
g_state = SnapState.NORMAL

function initialize(scene)

 
  g_kuruEngineInstance = KuruEngine.getInstance()
  kuruBody = KuruHumanActionExtension.cast(g_kuruEngineInstance:getExtension("KuruHumanAction"))
  scene:getInternalScene():setHandDetection(true)

  stickerNode = getStickerNode("f_hg.png",g_hgConfig.scale,g_hgConfig.location,g_hgConfig.anchor,g_hgConfig.tx,g_hgConfig.ty,0.0,g_hgConfig.flip,g_hgConfig.blendmode,g_hgConfig.fps)
  addNodeAndRelease(scene,stickerNode)
  stickerNode:setEnabled(false)

  init(scene)

  local leftNames = populateLeftParticleNames()
  local rightNames = populateRightParticleNames()

  setupParticles(leftNames, g_leftParticles)
  setupParticles(rightNames, g_rightParticles)

  buildParticles(scene)
  --showParticles(1)

  for i=1,5 do
    local name = "b_dd/b_dd_000"..(i-1)..".png"
    local g_sampler1 = getStickerSampler(name, g_config.fps)
    g_samplers[i] = g_sampler1
  end
  orisampler = getStickerSampler("b_dd/b_dd_0000.png", g_config.fps)
  samplerNode1 = getBgNodeWithSample(orisampler,g_config.scale,g_config.anchor,g_config.stretch,g_config.tx,g_config.ty,g_config.blendmode)
  addNodeAndRelease(scene,samplerNode1)

 
end
function showParticles(count)
          --count = 1
          for i=1,#g_leftParticles do
              if i~=count then
                g_leftParticles[i]:setEnabled(false)
              else
                g_leftParticles[i]:setEnabled(true)
              end
          end
          for j=1,#g_rightParticles do
            if j~=count then
              g_rightParticles[j]:setEnabled(false)
            else
              g_rightParticles[j]:setEnabled(true)
            end
          end
end
function frameReady(scene, elapsedTime)

  if SceneRenderConfig.instance():isRenderModePreview() then
      if(g_state==SnapState.CAPTRUEED or g_state==SnapState.VIDEOING) then
            resetState()
            g_state = SnapState.NORMAL
      end
  elseif  SceneRenderConfig.instance():isRenderModeSnapshot() then
      g_state = SnapState.CAPTRUEED
  elseif SceneRenderConfig.instance():isRenderModeVideo() then
      if(g_state==SnapState.NORMAL) then
          resetState()
          g_state=SnapState.VIDEOING
      end
  else
  
  end
  if isAning==true then

    g_frame_count=g_frame_count+1.0*0.5
    if g_frame_count>5 then
      g_frame_count = 1
    end

    orisampler:setTexture(g_samplers[math.modf(g_frame_count)]:getTexture())
    --print("g_frame_count"..math.modf(g_frame_count))
    
  else
    --print("g_frame_count"..math.modf(g_frame_count))
    
    g_totalElapsedTime = g_totalElapsedTime + elapsedTime
    if g_totalElapsedTime>5000 then
      samplerNode1:setEnabled(false)
    end
    if g_totalElapsedTime>22000 then
      -- g_leftParticles[g_frame_count]:emitOnce(0)
      -- g_leftParticles[g_frame_count]:stop()
      -- g_rightParticles[g_frame_count]:emitOnce(0)
      -- g_rightParticles[g_frame_count]:stop()
      --particleStopEmitOnce(0)
    else

      local currentFrameIndex = math.floor(g_totalElapsedTime / DURATION_PER_FRAME)
      local emitIntervalFrameCount = math.floor((1.0 ) * EMIT_COUNT_SCALE_FACTOR)
  
      if (g_lastEmitFrameIndex + emitIntervalFrameCount <= currentFrameIndex ) then
        g_lastEmitFrameIndex = currentFrameIndex
        print("发射"..g_frame_count)
        local offsetY = 1.0
        if g_frame_count==2 or g_frame_count==3 or g_frame_count==4 then
            offsetY = 1.1
        end
        emitOnPosition(0.3,offsetY,0.0,g_leftParticles[g_frame_count],g_frame_count)
        emitOnPosition(0.7,offsetY,0.0,g_rightParticles[g_frame_count],g_frame_count)
        --print("发射")
      end
    end
    if g_totalElapsedTime>23000 then
      resetState()
    end
   
  end
  
  
    local handCount = kuruBody:getHandCount()
  if handCount > 0 then
    for i = 0, handCount - 1 do
      local hand = kuruBody:getHandData(i)
      -- 目前只能识别手腕0点
      local point = hand:getKeyPoint(0)

      if point.x > -10000 then
        -- 比心手势
        local pointX = 720 * (hand:getKeyPoint(0).x + 1.0) / 2.0
        local pointY = 1280 * (hand:getKeyPoint(0).y + 1.0) / 2.0
        if pointY > 560 and pointY < 680 and pointX > 480 and pointX < 600 then
          if hand:isFingerIndex() then
            if isAning==true and g_bufferTime<0.2 then
              g_bufferTime=g_bufferTime+0.1
            else
              -- if g_leftParticles[g_frame_count]:isEnabled()==false then
              print("opening"..g_frame_count)
              isAning = false
              g_bufferTime = 0.0
              g_frame_count = math.modf(g_frame_count)
              --g_frame_count = 1

                showParticles(g_frame_count)
                if g_frame_count==3 then
                  stickerNode:setEnabled(true)
                else
                 stickerNode:setEnabled(false)
                end
              -- end
            
            end
          end
        end
      end
    end
  end


end
function emitOnWithIndex(count)

end
function resetState()
    stickerNode:setEnabled(false)
    samplerNode1:setEnabled(true)
    isAning = true
    g_bufferTime = 0.0
    g_frame_count = 1
    showParticles(0)
    g_lastEmitFrameIndex = 0
    g_totalElapsedTime = 4000
  
end
function finalize(scene)
  for i=1,#g_samplers do
      g_samplers[i]:release()
  end
end


function getSnapshot(scene)
  local node = KuruSnapshotNode.create()

  scene:addNode(node)
  node:release()

  return node
end

function addNodeAndRelease(scene, node)
  scene:addNode(node)
  node:release()
  return node
end

function setupParticles(particleNames, particles)
  for i, name in ipairs(particleNames) do
    particle = KuruParticleNode.create(getFilePath(name))
    table.insert(particles, particle)
  end
end

function init(scene)
  --CAMERA NODE CREATE
  local gyroParentCameraNode = KuruCameraNode.create(45, 10, 10000)
  g_gyroCameraNode = KuruCameraNode.create(45, 10, 10000)

  gyroParentCameraNode:addChild(g_gyroCameraNode)

  scene:addNode(gyroParentCameraNode)
  gyroParentCameraNode:release()
  g_gyroCameraNode:release()
end

function normalizeToZeroToOne(minusOneToOneVec2)
  local normalizedX = (minusOneToOneVec2.x + 1.0) / 2.0
  local normalizedY = (minusOneToOneVec2.y + 1.0) / 2.0

  return Vector2.create(normalizedX, normalizedY)
end

function buildParticles(scene)
  addParticles(g_leftParticles)
  addParticles(g_rightParticles)

  local kuruCameraNode = KuruCameraNode.create(45, 10, 10000)
  scene:addNode(kuruCameraNode)
  kuruCameraNode:release()
  particleStopEmitOnce(0)
end

function addParticles(particles)
  for i, particle in ipairs(particles) do
    particle:setBillboard(true)
    particle:start()
    g_gyroCameraNode:addChild(particle)
    particle:release()
  end
end

function particleStartEmitOnce(count, particle)
  --for i, particle in ipairs(particles) do
    particle:emitOnce(count)
    particle:start()
  --end
end

function particleStopEmitOnce(count)
  for i, particle in ipairs(g_leftParticles) do
    particle:emitOnce(count)
    particle:stop()
  end

  for i, particle in ipairs(g_rightParticles) do
    particle:emitOnce(count)
    particle:stop()
  end
end

function emitOnPosition(posX, posY, posYGap, particle,i)
  local resolution = g_kuruEngineInstance:getResolution()

  camera = g_gyroCameraNode:getCamera()
  local distance = camera:getFitDistance(resolution.x);

  --for i, particle in ipairs(particles) do
    local x = (1.0 - posX - 0.5)
    local y = (posY - 0.5)
    local transX = x * resolution.x
    local transY = (y + (i - 1) * posYGap) * resolution.y
    local vec3 = Vector3.create(transX, transY, distance)
    local emitter = ParticleEmitter.cast(particle:getParticleEmitter())
    emitter:setPosition(vec3, emitter:getPositionVariance());
  --end
  particleStartEmitOnce(1, particle)
end

function getFilePath(fileName)
    return BASE_DIRECTORY .. fileName
end

function getFragmentShader(filePath)
  return KuruShaderFilterNode.createWithFragmentShaderFile(BASE_DIRECTORY .. filePath, true)
end
function getStickerSampler(filepath,fps)
  local sp = KuruAnimationSampler.createFromPath(BASE_DIRECTORY..filepath,false,false)
  sp:setRepeatCount(0)
  sp:setFPS(fps)
  sp:play()
  return sp
end

function getBgNodeWithSample(sampler,scale,anchor,stretch,tx,ty,blendmode)
  local node = KuruBackgroundImageNode.createFromSampler(sampler,blendmode)
  node:setAnchorType(anchor)
  node:setStretch(stretch)
  node:setScale(scale,scale,1)
  node:setTranslation(tx,ty,0)
  return node
end

function getStickerNode(filePath, scale, loactionType, anchorType, translateX, translateY, translateZ, flip, blendMode, fps)
  local sampler = getStickerSampler(filePath, fps)
  local node = KaleStickerNode.createFromSampler(sampler, blendMode, -1, -1)

  if flip then
    node:setScale(-scale, scale, 0)
  else
    node:setScale(scale, scale, 0)
  end

  node:setId("sticker")
  node:setLocationType(loactionType)
  node:setAnchorType(anchorType)
  node:setTranslation(translateX, translateY, translateZ)
  local item = node:getStickerItem()
  item:getConfig().faceOffset =  Vector3.create(0.0,0.0,-0.58)
  sampler:release()

  return node
end